print("Loading models...1/11.")
import os
print("Loading models...2/11.")
import cv2
print("Loading models...3/11.")
import wave
print("Loading models...4/11.")
import time
print("Loading models...5/11.")
import numpy
print("Loading models...6/11.")
import pyaudio
print("Loading models...7/11.")
import keyboard
print("Loading models...8/11.")
import threading
print("Loading models...9/11.")
import tkinter.filedialog
print("Loading models...10/11.")
from PIL import Image,ImageGrab
print("Loading models...11/11. Loading this model may cost more time.")
from moviepy.editor import AudioFileClip,VideoFileClip

class ScreenRecorder:
    def get_fps(self,frame_count,cost_time):
        tmp_fps=float(frame_count)/float(cost_time)
        if int(tmp_fps)!=int(tmp_fps+0.5):
            return int(tmp_fps+0.5)
        return int(tmp_fps)
    def delete_image(self):
        for i in range(len(image_list)):
            os.remove(image_list[i])
            if(self.can_print_delete):
                print("Delete image...%d/%d"%(i+1,len(image_list)))
        os.rmdir("C:/ScreenRecorderTemp/Image%s"%self.now)
    def record_video(self):
        global frame_count,fps,image_list
        frame_count=0
        screen=ImageGrab.grab()
        size=screen.size
        #video=cv2.VideoWriter(self.video_record_filename,cv2.VideoWriter_fourcc('M','P','4','2'),FPS,screen.size)
        image_list=[]
        try:
            os.mkdir("C:/ScreenRecorderTemp/Image%s"%self.now)
        except:
            pass
        while self.recording:
            #video.write(cv2.cvtColor(numpy.array(ImageGrab.grab()),cv2.COLOR_RGB2BGR))
            img=ImageGrab.grab()
            path="C:/ScreenRecorderTemp/Image%s/%d.jpg"%(self.now,int(time.time()*1000))
            image_list.append(path)
            img.save(path)
            frame_count+=1
        fps=self.get_fps(frame_count,self.cost_time)
        video=cv2.VideoWriter(self.video_record_filename,cv2.VideoWriter_fourcc('M','P','4','2'),fps,size)
        for i in range(len(image_list)):
            print("Write %d/%d frame to pure video file."%(i+1,len(image_list)))
            video.write(cv2.cvtColor(numpy.array(Image.open(image_list[i])),cv2.COLOR_RGB2BGR))
        video.release()
    def record_audio(self):
        recordAudio=pyaudio.PyAudio()
        stream=recordAudio.open(format=pyaudio.paInt16,
                                channels=2,
                                rate=44100,
                                input=True,
                                frames_per_buffer=10240)
        waveFile=wave.open(self.audio_record_filename,'wb')
        waveFile.setnchannels(2)
        waveFile.setsampwidth(recordAudio.get_sample_size(pyaudio.paInt16))
        waveFile.setframerate(44100)
        while self.recording:
            data=stream.read(10240)
            waveFile.writeframes(data)
        stream.stop_stream()
        stream.close()
        recordAudio.terminate()
        waveFile.close()
    def run(self):
        print("If you are ready, please press Ctrl+Alt+S to continue.")
        keyboard.wait("ctrl+alt+s")
        try:
            os.mkdir("C:/ScreenRecorderTemp")
        except:
            pass
        self.now=str(time.strftime('%Y-%m-%d-%H-%M-%S',time.localtime(time.time())))
        self.audio_record_filename="C:/ScreenRecorderTemp/%s.mp3"%self.now
        self.video_record_filename="C:/ScreenRecorderTemp/%s.avi"%self.now
        t1=threading.Thread(target=self.record_audio)
        t2=threading.Thread(target=self.record_video)
        t3=threading.Thread(target=self.delete_image)
        print("Start.")
        self.can_print_delete=False
        self.recording=True
        time1=time.time()
        t1.start()
        t2.start()
        keyboard.wait("ctrl+alt+q")
        print("End.")
        time2=time.time()
        self.cost_time=time2-time1
        self.recording=False
        result_path=tkinter.filedialog.asksaveasfilename(title=u'录屏已完成，请选择文件保存路径', filetypes=[("MP4", ".mp4")])
        t1.join()
        t2.join()
        t3.start()
        audio=AudioFileClip(self.audio_record_filename)
        video=VideoFileClip(self.video_record_filename)
        audio_time=audio.duration
        video_time=video.duration
        video=video.fl_time(lambda t:(float(video_time)/float(audio_time))*t,apply_to=['mask','video','audio']).set_end(audio_time)
        totalVideo=video.set_audio(audio)
        if result_path[-4:]!=".mp4":
            result_path+=".mp4"
        print("Merge pure video files and audio files. Please be patient. It will take a long time.")
        totalVideo.write_videofile(result_path,codec="libx264",fps=self.get_fps(frame_count,self.cost_time))
        print("Finish. You can see the result now.")
        self.can_print_delete=True
        os.remove(self.audio_record_filename)
        os.remove(self.video_record_filename)
        t3.join()
sr=ScreenRecorder()
sr.run()
